/**工作者线程 */
// 工作者线程（Worker）是指在浏览器环境中运行的一种独立的JavaScript线程，用于执行一些耗时的计算或处理任务，以避免阻塞主线程，提高页面的响应性能。
// 工作者线程与主线程是相互独立的，它们之间可以通过消息传递进行通信。工作者线程可以执行一些复杂的计算、数据处理、网络请求等任务，而不会影响到主线程的运行和页面的交互。

/**工作者线程类型 */
// Dedicated Worker（专用工作者线程）：专用工作者线程是指与创建它的脚本相关联的工作者线程。
// 它只能被创建它的脚本所使用，是一种专门为一个特定脚本而创建的工作者线程。专用工作者线程可以通过JavaScript的Worker构造函数创建。
var worker = new Worker('worker.js');

// Shared Worker（共享工作者线程）：共享工作者线程是一种可以被多个脚本共享的工作者线程。
// 它可以被多个不同的脚本所连接和使用，是一种用于多个浏览上下文之间共享数据和通信的工作者线程。共享工作者线程可以通过JavaScript的SharedWorker构造函数创建。

var sharedWorker = new SharedWorker('sharedWorker.js');

// 这两种类型的工作者线程都可以执行一些耗时的计算、数据处理、网络请求等任务，以提高Web应用程序的性能和响应性能。
// 专用工作者线程与创建它的脚本相关联，而共享工作者线程可以被多个不同的脚本所共享使用。开发者可以根据具体的需求选择适合的工作者线程类型来提高Web应用程序的性能。

/**workerGlobalScope */

// WorkerGlobalScope是Web Worker中的全局作用域，它类似于浏览器环境中的window对象。WorkerGlobalScope提供了一些全局属性和方法，用于在工作者线程中执行任务和与主线程进行通信。
// 在WorkerGlobalScope中，可以使用以下一些重要的属性和方法：
// self：指向WorkerGlobalScope自身的引用，可以用于在工作者线程中引用当前全局作用域。
// onmessage：用于监听来自主线程的消息，当主线程发送消息时，可以通过该事件处理程序进行处理。
// postMessage()：用于向主线程发送消息，可以通过该方法向主线程发送数据。
// close()：用于关闭工作者线程。
// 在WorkerGlobalScope中，开发者可以编写工作者线程的逻辑，处理来自主线程的消息，执行耗时的计算任务，进行数据处理等操作。
// 通过WorkerGlobalScope提供的方法和事件，工作者线程可以与主线程进行通信，实现多线程的并行处理，提高Web应用程序的性能和响应速度。


/**专用工作者线程（后台脚本） */
//注意不能使用非同源脚本创建工作者线程
// 专用工作者线程（Dedicated Worker）是Web Worker的一种类型，它是与创建它的脚本相关联的工作者线程。
// 专用工作者线程只能被创建它的脚本所使用，是一种专门为一个特定脚本而创建的工作者线程。
var worker = new Worker('worker.js');
// 在这里，'worker.js' 是要在专用工作者线程中执行的JavaScript文件。专用工作者线程可以执行一些耗时的计算、数据处理、网络请求等任务，
// 以提高Web应用程序的性能和响应性能。专用工作者线程与创建它的脚本相关联，只能被创建它的脚本所使用。

/**使用worker对象 */
// 创建Worker对象：通过JavaScript代码创建一个新的Worker对象，指定要在工作者线程中执行的JavaScript文件。
var worker = new Worker('worker.js');
// 监听消息：在主线程中，可以通过监听Worker对象的onmessage事件来接收来自工作者线程的消息。
worker.onmessage = function (event) {
    console.log('Received message from worker: ' + event.data);
};
// 发送消息：在主线程中，可以通过postMessage方法向工作者线程发送消息。
worker.postMessage('Hello from main thread!');
// 在工作者线程中执行任务：在指定的worker.js文件中编写要在工作者线程中执行的JavaScript代码。
// worker.js
self.onmessage = function (event) {
    console.log('Received message from main thread: ' + event.data);
    self.postMessage('Hello from worker!');
};

// worker事件
// onmessage：当工作者线程接收到来自主线程的消息时触发。在工作者线程中，可以通过监听这个事件来处理来自主线程的消息。
worker.onmessage = function (event) {
    console.log('Received message from main thread: ' + event.data);
};
// onerror：当工作者线程内部发生错误时触发。可以通过监听这个事件来处理工作者线程中的错误情况。
worker.onerror = function (event) {
    console.error('Worker error: ' + event.message);
};
// onmessageerror：当在工作者线程中接收到无效的消息时触发。可以通过监听这个事件来处理消息接收错误的情况。
worker.onmessageerror = function (event) {
    console.error('Invalid message received in worker: ' + event.data);
};
// onterminate：当工作者线程被终止时触发。可以通过监听这个事件来执行一些清理操作或处理工作者线程被终止的情况。
worker.onterminate = function (event) {
    console.log('Worker terminated');
};

// DedicatedWorkerGlobalScoped

// DedicatedWorkerGlobalScope接口提供了一些特定于Worker的功能和属性，类似于浏览器中的全局对象（如window对象）。它是Worker线程中的顶级对象，可以通过self关键字来访问。

// 在DedicatedWorkerGlobalScope中，可以定义全局变量、函数和事件处理程序等。它还提供了一些与Worker线程相关的方法和属性，例如：

// self.postMessage(data): 向创建该Worker的主线程发送消息。
// self.onmessage: 用于处理从主线程接收到的消息的事件处理程序。
// self.close(): 关闭Worker线程。
// 以下是一个使用DedicatedWorkerGlobalScope的简单示例：
// worker.js
self.onmessage = function (event) {
    var message = event.data;
    console.log('Received message from main thread:', message);

    var result = doSomeHeavyTask(message);

    self.postMessage(result);
};

function doSomeHeavyTask(data) {
    // 执行一些耗时的任务
    // 返回结果
}
// 在上述示例中，worker.js文件表示一个Worker线程。它通过self.onmessage事件处理程序接收来自主线程的消息，并执行一些耗时的任务。然后，使用self.postMessage方法将结果发送回主线程。
// 在主线程中，可以通过创建Worker对象来启动Worker线程，并与之通信。例如：
// main.js
var worker = new Worker('worker.js');

worker.onmessage = function (event) {
    var result = event.data;
    console.log('Received result from worker:', result);
};

worker.postMessage('Hello from main thread!');
// 在上述示例中，main.js文件表示主线程。它创建一个Worker对象，并通过worker.postMessage方法向Worker线程发送消息。然后，通过worker.onmessage事件处理程序接收来自Worker线程的结果。

// 通过使用DedicatedWorkerGlobalScope接口，可以在Worker线程中执行一些耗时的任务，而不会阻塞主线程。这对于处理大量数据、执行复杂计算或与后端进行交互等场景非常有用。

/**生命周期 */
// 创建阶段：通过创建Worker对象来创建专用工作者线程。例如：
var worker = new Worker('worker.js');
// 在创建Worker对象时，会启动一个新的专用工作者线程，并加载指定的JavaScript文件。
// 运行阶段：在专用工作者线程中执行JavaScript代码。例如：
// worker.js
self.onmessage = function (event) {
    var message = event.data;
    console.log('Received message from main thread:', message);

    var result = doSomeHeavyTask(message);

    self.postMessage(result);
};

function doSomeHeavyTask(data) {
    // 执行一些耗时的任务
    // 返回结果
}
// 在运行阶段中，专用工作者线程会执行指定的JavaScript代码，并通过self.onmessage事件处理程序接收来自主线程的消息，并执行一些耗时的任务。然后，使用self.postMessage方法将结果发送回主线程。
// 关闭阶段：通过调用Worker对象的terminate方法来关闭专用工作者线程。例如：
worker.terminate();
// 在关闭阶段中，可以通过调用Worker对象的terminate方法来关闭专用工作者线程。在关闭之前，可以通过self.onclose事件处理程序执行一些清理操作。

/**配置worker选项 */
// type：指定Worker的类型，可以是"classic"或"module"。默认值为"classic"。"classic"类型的Worker可以使用全局作用域，而"module"类型的Worker可以使用ES模块的导入和导出功能。
var worker = new Worker('worker.js', { type: 'classic' });
// name：指定Worker的名称，用于调试和识别目的。
var worker = new Worker('worker.js', { name: 'MyWorker' });
// credentials：指定Worker是否应该发送凭据（如cookie）到服务器。可以是"omit"、"same-origin"或"include"。默认值为"omit"。
var worker = new Worker('worker.js', { credentials: 'include' });
// deno：指定Worker是否应该在Deno环境中运行。默认值为false。
var worker = new Worker('worker.js', { deno: true });
// workerOptions：指定Worker的其他选项，可以是一个对象，用于传递自定义选项。
var worker = new Worker('worker.js', { workerOptions: { myOption: true } });
 
/**importScripts */
// importScripts是在专用工作者线程中加载外部脚本的方法。它允许在专用工作者线程中导入其他JavaScript脚本文件，以便在该线程中使用导入的函数、变量和对象。
// importScripts的语法如下：
importScripts('script1.js', 'script2.js', '其他');

/**共享工作者线程 */
// 共享工作者线程（SharedWorker）是一种特殊的Web Worker，它可以被多个窗口或标签页共享。与专用工作者线程不同，共享工作者线程可以在多个上下文中运行，包括不同的窗口、标签页或甚至不同的浏览器。
// 共享工作者线程的创建方式与专用工作者线程类似，只是需要使用SharedWorker构造函数来创建共享工作者线程对象。示例代码如下：
var worker = new SharedWorker('worker.js');
// 在上面的代码中，worker.js是共享工作者线程的脚本文件路径。创建共享工作者线程对象后，可以通过port属性来与共享工作者线程进行通信。示例代码如下：
var worker = new SharedWorker('worker.js');
worker.port.addEventListener('message', function (event) {
    console.log('Received message:', event.data);
});
worker.port.postMessage('Hello from main thread!');
// 在上面的代码中，addEventListener方法用于监听共享工作者线程发送的消息，postMessage方法用于向共享工作者线程发送消息。
// 需要注意的是，共享工作者线程的生命周期与其所连接的窗口或标签页相同。当所有连接的窗口或标签页都关闭时，共享工作者线程也会被终止。

/**共享工作者线程生命周期 */
// 共享工作者线程的生命周期与其所连接的窗口或标签页相同。当所有连接的窗口或标签页都关闭时，共享工作者线程也会被终止。

// 具体来说，当一个窗口或标签页连接到共享工作者线程时，会创建一个MessagePort对象，用于在窗口或标签页与共享工作者线程之间传递消息。
// 当所有连接的窗口或标签页都关闭时，这些MessagePort对象也会被关闭，从而导致共享工作者线程的终止。

// 需要注意的是，共享工作者线程的终止并不会立即发生。当最后一个连接的窗口或标签页关闭时，共享工作者线程会进入一个“等待终止”状态，
// 等待一段时间后再进行终止。这个等待时间可以通过close()方法的参数来指定，
// 如果不指定则默认为30秒。在等待时间内，如果有新的窗口或标签页连接到共享工作者线程，那么共享工作者线程的终止会被取消，直到所有连接的窗口或标签页都关闭为止。

// 另外，共享工作者线程的终止也可以通过调用close()方法来手动触发。当调用close()方法时，共享工作者线程会立即进入“等待终止”状态
// ，并开始倒计时等待时间。如果在等待时间内没有新的窗口或标签页连接到共享工作者线程，那么共享工作者线程会被终止。
// 如果在等待时间内有新的窗口或标签页连接到共享工作者线程，那么共享工作者线程的终止会被取消，直到所有连接的窗口或标签页都关闭为止。

/**服务工作者线程 */
// 服务工作者线程（Service Worker）是一种在浏览器后台运行的脚本，它可以独立于网页进行操作。服务工作者线程可以用于实现离线缓存、消息推送、网络代理等功能，使得网页可以在离线状态下提供基本的功能和体验。
// 服务工作者线程的生命周期相对于网页而言更加独立。它可以在网页关闭后继续运行，并且可以在网页重新打开时重新连接。服务工作者线程的生命周期包括以下几个阶段：
// 1. 注册：在网页中通过`navigator.serviceWorker.register()`方法注册服务工作者线程。注册成功后，浏览器会下载并安装服务工作者线程脚本。

// 2. 安装：在安装阶段，服务工作者线程会被下载并缓存，但尚未激活。在安装阶段，可以进行一些初始化操作，如缓存静态资源等。

// 3. 激活：在激活阶段，服务工作者线程会替代之前的旧版本，成为当前活动的服务工作者线程。在激活阶段，可以进行一些清理操作，如删除旧版本的缓存等。

// 4. 运行：在运行阶段，服务工作者线程可以监听来自网页的事件，如拦截和处理网络请求、处理推送消息等。它可以在后台运行，独立于网页的生命周期。

// 需要注意的是，服务工作者线程的生命周期是由浏览器控制的，它可能会在某些条件下被终止或重新启动。例如，当浏览器关闭或重新启动时，服务工作者线程会被终止并重新启动。
//此外，浏览器还会根据一些策略来管理服务工作者线程的资源使用，以确保性能和安全性。
// 总的来说，服务工作者线程的生命周期相对独立，可以在后台运行，并提供离线缓存、消息推送等功能，为网页提供更好的用户体验。